azure CLI

2022-02-18 ยท 4 min read

Initial Setup #

Setup an Azure account: https://portal.azure.com.

Install the CLI #

Debian/Ubuntu/WSL #

$ curl -sL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/microsoft.gpg > /dev/null

$ AZ_REPO=$(lsb_release -cs) echo "deb [arch=amd64] https://packages.microsoft.com/repos/azure-cli/ $AZ_REPO main" | sudo tee /etc/apt/sources.list.d/azure-cli.list

$ sudo apt update
$ sudo apt-get install azure-cli

macOS #

$ brew update
$ brew install azure-cli

CLI Login #

$ az login

If this isn't inside a docker container, you can just run az login, which will open the browser for you. When doing this in WSL2, use az login --use-device-code and open https://microsoft.com/devicelogin separately.

View available regions #

# Pull out the "name" field in each object and sort them
$ az account list-locations \
	--query "[].name | sort(@)"

(Optional) Configure default region #

$ az configure --defaults location=westus

Create a resource group #

$ az group create \
	--location westus \
	--name az account list-locations --query "[].name | sort(@)"

{
  "id": "/subscriptions/XXXXX-XXXX-XXXX-XXXX-XXXXX/resourceGroups/mygroup",
  "location": "westus",
  "managedBy": null,
  "name": "mygroup",
  "properties": {
    "provisioningState": "Succeeded"
  },
  "tags": null,
  "type": "Microsoft.Resources/resourceGroups"
}

(Optional) Configure default resource group #

$ az configure --defaults group=mygroup

Create our VM #

  • Note: Azure only supports uploading RSA keys via the CLI (i.e., not Ed25519 or ECDSA). The bit-length must also be at least 2048. Don't worry though, we'll toss our usual Ed25519 pubkeys into the VM in just a sec!
$ az vm create \
	--name myvm \
	--size Standard_DC1s_v3 \
	--image Canonical:0001-com-ubuntu-server-focal:20_04-lts-gen2:latest \
	--authentication-type ssh \
	--ssh-key-values ~/.ssh/id_rsa4096.pub \
	--public-ip-sku Basic \
	--public-ip-address-dns-name "my-unique-name" \
	--public-ip-address-allocation Dynamic \
	--storage-sku "Standard_LRS"

{
  "fqdns": "my-unique-name.westus.cloudapp.azure.com",
  "id": "/subscriptions/XXXXX-XXXX-XXXX-XXXX-XXXXX/resourceGroups/mygroup/providers/Microsoft.Compute/virtualMachines/myvm",
  "location": "westus",
  "macAddress": "XX-XX-XX-XX-XX-XX",
  "powerState": "VM running",
  "privateIpAddress": "10.0.0.4",
  "publicIpAddress": "XX.XX.XX.XX",
  "resourceGroup": "mygroup",
  "zones": ""
}

Let's quickly confirm that the DNS name resolves correctly:

$ dig +short A my-unique-name.westus.cloudapp.azure.com
XX.XX.XX.XX

Then let's make sure we can at least SSH into the VM:

$ ssh -i ~/.ssh/id_rsa4096 my-unique-name.westus.cloudapp.azure.com

We can also dump all of our github pubkeys into the VM, so we don't need the -i arg anymore : )

$ ssh -i ~/.ssh/id_rsa4096 \
	my-unique-name.westus.cloudapp.azure.com \
	"curl \"https://github.com/phlip9.keys\" >> ~/.ssh/authorized_keys"

(FIXUP) Create a public IPv4+IPv6 addr + DNS record #

  • Note: the dns-name label must be unique across all customers in a region!
  • The final DNS name will look like <dns-name>.<location>.cloudapp.azure.com.

See: Azure Docs - virtual network public IP

See: Azure - public IP address pricing

# Create the IPv4 address
$ az network public-ip create \
	--name "mygroup-ip" \
	--allocation-method Dynamic \
	--dns-name "my-unique-name" \
	--sku Basic \
	--version IPv4

# Create the IPv6 address
$ az network public-ip create \
	--name "mygroup-ip" \
	--allocation-method Dynamic \
	--dns-name "my-unique-name" \
	--sku Basic \
	--version IPv6

{
  "publicIp": {
    "ddosSettings": null,
    "deleteOption": null,
    "dnsSettings": {
      "domainNameLabel": "my-unique-name",
      "fqdn": "my-unique-name.westus.cloudapp.azure.com",
      "reverseFqdn": null
    },
    "etag": "W/\"XXXXXX-XXXX-XXXX-XXXX-XXXXXX\"",
    "extendedLocation": null,
    "id": "/subscriptions/XXXXXX-XXXX-XXXX-XXXX-XXXXXX/resourceGroups/mygroup/providers/Microsoft.Network/publicIPAddresses/mygroup-ip",
    "idleTimeoutInMinutes": 4,
    "ipAddress": null,
    "ipConfiguration": null,
    "ipTags": [],
    "linkedPublicIpAddress": null,
    "location": "westus",
    "migrationPhase": null,
    "name": "mygroup-ip",
    "natGateway": null,
    "provisioningState": "Succeeded",
    "publicIpAddressVersion": "IPv6",
    "publicIpAllocationMethod": "Dynamic",
    "publicIpPrefix": null,
    "resourceGroup": "sgxdev",
    "resourceGuid": "XXXXXX-XXXX-XXXX-XXXX-XXXXXX",
    "servicePublicIpAddress": null,
    "sku": {
      "name": "Basic",
      "tier": "Regional"
    },
    "tags": null,
    "type": "Microsoft.Network/publicIPAddresses",
    "zones": null
  }
}